package com.lau.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lau.constant.CacheConstants;
import com.lau.entity.SysMenu;
import com.lau.entity.SysRole;
import com.lau.entity.SysUser;
import com.lau.mapper.SysUserMapper;
import com.lau.service.SysMenuService;
import com.lau.service.SysRoleService;
import com.lau.service.SysUserService;
import com.lau.utils.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author Lau
 * @since 2023-11-18
 */
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {

    @Autowired
    SysRoleService sysRoleService;

    @Autowired
    SysUserMapper sysUserMapper;

    @Autowired
    SysMenuService sysMenuService;

    @Autowired
    RedisUtil redisUtil;

    @Override
    public SysUser getByUsername(String username) {
        return getOne(new QueryWrapper<SysUser>().eq("username", username));
    }

    @Override
    public String getUserAuthorityInfo(Long userId) {
        SysUser sysUser = sysUserMapper.selectById(userId);
        //  ROLE_admin,ROLE_normal,sys:user:list,....
        String authority = "";
        if (redisUtil.hasKey(CacheConstants.GRANTED_AUTHORITY + sysUser.getUsername())) {
            authority = (String) redisUtil.get(CacheConstants.GRANTED_AUTHORITY + sysUser.getUsername());
        } else {
            //获取当前用户对应的角色集合
            List<SysRole> roles = sysRoleService.list(new QueryWrapper<SysRole>()
                    .inSql("id", "select role_id from sys_user_role where user_id = " + userId));

            if (CollUtil.isNotEmpty(roles)) {
                //将角色集合转化成以ROLE_开头的权限表示，并与权限集合被合并
                String roleCodes = roles.stream().map(r -> "ROLE_" + r.getRoleCode()).collect(Collectors.joining(","));
                authority = roleCodes.concat(",");
            }
            // 获取菜单操作编码
            List<Long> menuIds = sysUserMapper.getNavMenuIds(userId);
            if (!menuIds.isEmpty()) {
                List<SysMenu> menus = sysMenuService.listByIds(menuIds);
                String menuPerms = menus.stream().map(SysMenu::getPerms).collect(Collectors.joining(","));
                authority = authority.concat(menuPerms);
            }
            redisUtil.set(CacheConstants.GRANTED_AUTHORITY + sysUser.getUsername(), authority, 60 * 60);
        }

        return authority;
    }

    @Override
    public void clearUserAuthorityInfo(String username) {
        redisUtil.del(CacheConstants.GRANTED_AUTHORITY + username);
    }

    @Override
    public void clearUserAuthorityInfoByRoleId(Long roleId) {

        List<SysUser> sysUsers = this.list(new QueryWrapper<SysUser>()
                .inSql("id", "select user_id from sys_user_role where role_id = " + roleId));
        sysUsers.forEach(u -> this.clearUserAuthorityInfo(u.getUsername()));

    }

    @Override
    public void clearUserAuthorityInfoByMenuId(Long menuId) {
        List<SysUser> sysUsers = sysUserMapper.listByMenuId(menuId);
        sysUsers.forEach(u -> {
            this.clearUserAuthorityInfo(u.getUsername());
        });
    }

    @Override
    public Page<SysUser> pageUserByUserName(Page<SysUser> page, String username) {
        Page<SysUser> sysUserPage = sysUserMapper.pageUserByUserName(page, username);
        sysUserPage.getRecords().forEach(info -> {
            info.setRoleNameList(StrUtil.split(info.getRoleName(), ','));
        });
        return sysUserPage;
    }
}
